#!/usr/bin/env python

from bluetooth import *
import pynotify
import Enumerate
import pygtk
import rfcomm_client
pygtk.require('2.0')
import gtk

window_w = 300
window_h = 400

# Backing pixmap for drawing area
pixmap = None
_notifications = None
sock = None

class Notification:	
	def __init__(self):
		if not pynotify.init("eftdum daemon"):
			print "Eroare la initializare :("

	def show_notify(self, title, text, tip):
		self.notify = pynotify.Notification(title, text, gtk.STOCK_CONNECT)
		self.notify.show()

def disconnect_bd_device(event, w=None):
	global sock
	# close any existing sockets
	if sock != None:
		sock.close()
		_notifications.show_notify("AWESOME-O", "Disconnected!", None)
	else:
		_notifications.show_notify("AWESOME-O", "Cannont disconnect: was not connected :(", None)
	

def connect_to_bd_device(event, w=None):
	global sock
	# close any existing sockets
	if sock != None:
		sock.close()
	# run a dialog to chose the device
	sock = rfcomm_client.choose_bt_device_and_connect()
	if sock != None:
		_notifications.show_notify("AWESOME-O", "Connected!", None)
	else:
		_notifications.show_notify("AWESOME-O", "Could not connect :(", None)


def si_show_about(event, w=None):
	ad = gtk.AboutDialog()
	icon = gtk.gdk.pixbuf_new_from_file("icons/tango_bluetooth_48.png")
	ad.set_logo(icon)
	ad.set_name("AWESOME-O - Control Bluetooth")
	ad.set_authors(["Raluca Elena Podiuc <ralucaelena1985@gmail.com>"])
	ad.set_comments("Control daemon for AWESOME-O - the probing bot.")
	ad.set_version('0.1')
	ad.run()
	ad.destroy()


def erase_image(pixmap, widget):
    x, y, width, height = widget.get_allocation()
    print x, y, width, height
    print widget
    pixmap.draw_rectangle(widget.get_style().white_gc,
                          True, 0, 0, width, height)


# Create a new backing pixmap of the appropriate size
def configure_event(widget, event):
    global pixmap
    x, y, width, height = widget.get_allocation()
    print "conf ", x, y, width, height
    pixmap = gtk.gdk.Pixmap(widget.window, width, height)
    erase_image(pixmap, widget)
    return True

# Redraw the screen from the backing pixmap
def expose_event(widget, event):
    x , y, width, height = event.area
    widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
                                pixmap, x, y, x, y, width, height)
    return False

_erase_image = True
# Draw a rectangle on the screen
def draw_brush(widget, x, y):
    global _erase_image
    rect = (int(x-5), int(y-5), 10, 10)
    #print "_erase_image_erase_image_erase_image_erase_image_erase_imageX", _erase_image
    if _erase_image:
        x, y, width, height = widget.get_allocation()
        print "_erase_imagex=", _erase_image, x, y, width, height
        pixmap.draw_rectangle(widget.get_style().white_gc, True,
                              x, y, width, height)
        widget.queue_draw_area(x, y, width, height)
        _erase_image = not _erase_image
        
    pixmap.draw_rectangle(widget.get_style().black_gc, True,
                          rect[0], rect[1], rect[2], rect[3])
    widget.queue_draw_area(rect[0], rect[1], rect[2], rect[3])

def button_press_event(widget, event):
    global pixmap
    global _erase_image
    if event.button == 1 and pixmap != None:
        print "mmmm"
        _erase_image = True
        draw_brush(widget, event.x, event.y)
    return True

def motion_notify_event(widget, event):
    if event.is_hint:
        x, y, state = event.window.get_pointer()
    else:
        x = event.x
        y = event.y
        state = event.state
    
    if state & gtk.gdk.BUTTON1_MASK and pixmap != None:
        draw_brush(widget, x, y)
  
    return True












item_factory = None
def _get_main_menu(window, menu_items):
	global item_factory
        accel_group = gtk.AccelGroup()

	# This function initializes the item factory.
        # Param 1: The type of menu - can be MenuBar, Menu,
        #          or OptionMenu.
        # Param 2: The path of the menu.
        # Param 3: A reference to an AccelGroup. The item factory sets up
        #          the accelerator table while generating menus.
	item_factory = gtk.ItemFactory(gtk.MenuBar, "<main>", accel_group)
	
        # This method generates the menu items. Pass to the item factory
        #  the list of menu items
        item_factory.create_items(menu_items)

        # Attach the new accelerator group to the window.
        window.add_accel_group(accel_group)
	
        # Finally, return the actual menu bar created by the item factory.
        return item_factory.get_widget("<main>")



def _make_menu_bar(window):
	global menu_items
	menu_items = (
		( "/_File",         None,         None, 0, "<Branch>" ),
		( "/File/Quit",     "<control>Q", gtk.main_quit, 0, None ),
		( "/File/Connect",  "<control>C", connect_to_bd_device, 0, None ),
		( "/File/Disconnect","<control>D", disconnect_bd_device, 0, None ),
		( "/_Options",      None,         None, 0, "<Branch>" ),
		( "/Options/Test",  None,         None, 0, None ),
		( "/_Help",         None,         None, 0, "<LastBranch>" ),
		( "/_Help/About",   None,         si_show_about, 0, None ),
		)
	menubar = _get_main_menu(window, menu_items)
	return menubar



def _mkbtn(text, box, func, window, stock=None):
	if stock==None:
		button = gtk.Button(text)
	else:
		button = gtk.Button(stock=stock)
	box.pack_start(button, False, False, 0)
 	button.connect_object("clicked", func, window)
	button.show()


def _mktabbtn(text, table, r, c, rx, cx, func, window, stock=None):
	if stock==None:
		button = gtk.Button(text)
	else:
		button = gtk.Button(stock=stock)
	table.attach(button, r, c, rx, cx)
 	button.connect_object("clicked", func, window)
	button.show()

direction=Enumerate.Enumeration('direction', ['BACK',  'FRONT', 'LEFT', 'RIGHT', 'STOP'])

def move(w, d):
	dir_str = direction.whatis(d)
	if sock == None:
		print "dir== ", dir_str
		return
	sock.send(dir_str + '\n')

def main():
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_name ("Test Input")

    vbox = gtk.VBox(False, 1)
    window.add(vbox)
    vbox.show()

    window.connect("destroy", lambda w: gtk.main_quit())
    menubar = _make_menu_bar(window)
    vbox.pack_start(menubar, False, True, 0)
    menubar.show()
    # Create the drawing area
    drawing_area = gtk.DrawingArea()
    drawing_area.set_size_request(window_w, window_h)
    vbox.pack_start(drawing_area, True, True, 0)

    drawing_area.show()

    # Signals used to handle backing pixmap
    drawing_area.connect("expose_event", expose_event)
    drawing_area.connect("configure_event", configure_event)

    # Event signals
    drawing_area.connect("motion_notify_event", motion_notify_event)
    drawing_area.connect("button_press_event", button_press_event)

    drawing_area.set_events(gtk.gdk.EXPOSURE_MASK
                            | gtk.gdk.LEAVE_NOTIFY_MASK
                            | gtk.gdk.BUTTON_PRESS_MASK
                            | gtk.gdk.POINTER_MOTION_MASK
                            | gtk.gdk.POINTER_MOTION_HINT_MASK)


    vbox1 = gtk.VBox(False, 0)
    vbox.add(vbox1)
    vbox1.show()

    btntable = gtk.Table(rows=3, columns=3, homogeneous=True)
    #_mktabbtn("",     btntable, 0, 1, 0, 1, lambda w: w.destroy() , window)
    _mktabbtn("FRONT", btntable, 1, 2, 0, 1, lambda w: move(w, direction.FRONT) , window)
    #_mktabbtn("",     btntable, 2, 3, 0, 1, lambda w: w.destroy() , window)
    _mktabbtn("LEFT",  btntable, 0, 1, 1, 2, lambda w: move(w, direction.LEFT) , window)
    _mktabbtn("STOP",  btntable, 1, 2, 1, 2, lambda w: move(w, direction.STOP) , window)
    _mktabbtn("RIGHT", btntable, 2, 3, 1, 2, lambda w: move(w, direction.RIGHT) , window)
    #_mktabbtn("",     btntable, 0, 1, 2, 3, lambda w: w.destroy() , window)
    _mktabbtn("BACK",  btntable, 1, 2, 2, 3, lambda w: move(w, direction.BACK) , window)
    #_mktabbtn("", btntable, 2, 3, 2, 3, lambda w: w.destroy() , window)

    vbox.add(btntable)
    btntable.show()

    hbox = gtk.HBox(False, 0)
    vbox1.add(hbox)
    hbox.show()


    button_conn  = _mkbtn("", hbox, connect_to_bd_device, window, stock=gtk.STOCK_CONNECT)
    button_about = _mkbtn("", hbox, si_show_about, window, stock=gtk.STOCK_ABOUT)
    button_quit  = _mkbtn("", hbox, lambda w: w.destroy(), window, stock=gtk.STOCK_QUIT)



    window.show()

    gtk.main()
    return 0


if __name__ == "__main__":
	_notifications = Notification()
	main()
